/**
 * COPYRIGHT (C) 2009. Denny Tran, Omar Jaime, David Deng, Julie Hsieh. All Rights Reserved
 * Class that represents an event within the calendar. 
 * @author Denny Tran, Omar Jaime, David Deng, Julie Hsieh 
 * @version 1.01 2009-05-05
 */

package data;
import java.util.Calendar;
import java.util.GregorianCalendar;

public class Event
{
   // private instance variable
   private String eventName;
   private String description;
   private String type;
   private String userName; // event owner = user XOR group
   private int eventID;
   private int groupID; // event owner = user XOR group
   private GregorianCalendar startTime;
   private GregorianCalendar endTime;

   // recurrance
   private boolean recurring;
   private boolean[] daysOfWeek; // boolean array of 7: 1=Sun,2=Mon,...etc
   private String recurranceType; // None, Weekly, Bi-weekly, Monthly,...etc

   /**
    * Construct the event object.
    * 
    * @param eventid The event's id within the database.
    * @param eventname The name of the event.
    * @param groupID The group's id that this event belongs to.
    * @param userName The owner of this event. blank if owned by group
    * @param type "event", "meeting" or "deadline"
    * @param start The start time of this event.
    * @param end The end time of this event.
    * @param description The description of this event.
    */
   public Event(int eventid, String eventname, int groupID, String userName,
         String type, GregorianCalendar start, GregorianCalendar end,
         String description, boolean recurring, boolean sun, boolean mon, 
         boolean tue, boolean wed, boolean thu, boolean fri, boolean sat)
   {
      this.eventID = eventid;
      setEvent(eventname, groupID, userName,
            type, start, end,
            description, recurring, sun, mon, 
            tue, wed, thu, fri, sat);
   }
   
   /**
    * Initializes the event to these fields.
    */
   private void setEvent(String eventname, int groupID, String userName,
         String type, GregorianCalendar start, GregorianCalendar end,
         String description, boolean recurring, boolean sun, boolean mon, 
         boolean tue, boolean wed, boolean thu, boolean fri, boolean sat)
   {
      this.eventName = eventname;
      this.groupID = groupID;    //XOR
      this.userName = userName;  //XOR
      this.type = type;
      this.startTime = start;
      this.endTime = end;
      this.description = description;
      
      this.recurring = recurring;
      daysOfWeek = new boolean[8]; // for setting recurring event; 0 not used
      daysOfWeek[1] = sun;
      daysOfWeek[2] = mon;
      daysOfWeek[3] = tue;
      daysOfWeek[4] = wed;
      daysOfWeek[5] = thu;
      daysOfWeek[6] = fri;
      daysOfWeek[7] = sat;
      //recurranceType = "None";
   }

   /**
    * Second Constuctor with no id information, please set
    * 
    * @param eventName The name of the event.
    * @param type "event", "meeting", "deadline"
    * @param start The start time of this event.
    * @param end The end time of this event.
    * @param description The description of this event.
    */
   public Event(String eventname, String type, GregorianCalendar start,
         GregorianCalendar end, String description, 
         boolean recurring, boolean sun, boolean mon, 
         boolean tue, boolean wed, boolean thu, boolean fri, boolean sat)
   {
      setEvent(eventname, groupID, userName,
            type, start, end,
            description, recurring, sun, mon, 
            tue, wed, thu, fri, sat);
   }
   
   
   /**
    * Creates an event with the given parameters. 
    */
   public Event(int eventid, String eventname, int groupID, String userName,
         String type, GregorianCalendar start, GregorianCalendar end,
         String description)
   {
      this.eventID = eventid;
      setEvent(eventname, groupID, userName,
            type, start, end,
            description, recurring, false, false, 
            false, false, false, false, false);
   }
   

   /** 
    * Prints out the information of this event.
    */
   public String toString()
   {
      return eventName + " (type=" + type + "): "
            + TwoPlaceString.getSqlTimestamp(startTime) + " to "
            + TwoPlaceString.getSqlTimestamp(endTime) + " recur=" + recurring
            + " " + description;
   }

   /**
    * Return the name of the event
    * 
    * @return name of the event
    */
   public String getEventName()
   {
      return eventName;
   }

   /**
    * Sets the name of the event.
    * @param eventName The name to set.
    */
   public void setEventName(String eventName)
   {
      this.eventName = eventName;
   }

   /**
    * Return the description of the event
    * 
    * @return description of the event
    */
   public String getDescription()
   {
      return description;
   }

   /**
    * Gets the type of this event.
    * @return The type of this event: "meeting", "event", or "deadline"
    */
   public String getType()
   {
      return type;
   }

   /**
    * Gets the start time of this event.
    * @return The start time of this event.
    */
   public GregorianCalendar getStartTime()
   {
      return startTime;
   }

   /**
    * Sets the start time of this event.
    * @param startTime The start time to set this event to.
    */
   public void setStartTime(GregorianCalendar startTime)
   {
      this.startTime = startTime;
   }

   /**
    * Gets the end time of this event.
    * @return The end time of the this event.
    */
   public GregorianCalendar getEndTime()
   {
      return endTime;
   }

   /**
    * Sets the end time of this event.
    * @param endTime The end time to set this event to.
    */
   public void setEndTime(GregorianCalendar endTime)
   {
      this.endTime = endTime;
   }

   /**
    * Gets the event ID of this event.
    * @return The event ID of this event.
    */
   public int getEventID()
   {
      return eventID;
   }

   /**
    * Sets the event ID of this event.
    * @param eventID The event ID to set this event to.
    */
   public void setEventID(int eventID)
   {
      this.eventID = eventID;
   }

   /**
    * Gets the group ID of this event.
    * @return The group ID of this event.
    */
   public int getGroupID()
   {
      return groupID;
   }

   /**
    * Sets the group ID of this event.
    * @param groupID The group ID to set this event to.
    */
   public void setGroupID(int groupID)
   {
      this.groupID = groupID;
   }

   /**
    * Gets the owner of this event.
    * @return The owner of this event or empty string if owned by group.
    */
   public String getUserName()
   {
      return userName;
   }

   /**
    * Sets the owner of this event.
    * @param userName The name of the owner of this event. 
    */
   public void setUserName(String userName)
   {
      this.userName = userName;
   }

   /**
    * This method set the recurrance info. This is only called when user wants
    * to create a recurring. Otherwise event is default to single one time
    * event.
    * 
    * @param daysOfWeek
    *           boolean array of which days (Sun,...,Sat)
    * @param type
    *           type of recurring event,
    */
   public void setRecurrence(boolean[] daysOfWeek, String type)
   {
      for(boolean day: daysOfWeek)
         if(day) recurring = true;

      this.daysOfWeek = daysOfWeek; // boolean array of 7: 0=Sun,1=Mon,...etc
      recurranceType = type; // Weekly, Bi-Weekly, Monthly, Yearly
   }

   /**
    * Getting days of recurrance, only usable if this is an recurring event.
    * 
    * @return boolean event with boolean info
    */
   public boolean[] getDaysOfWeek()
   {
      return daysOfWeek;
   }

   /**
    * Gets the recurrence type of this event.
    * @return The recurrence type of this event.
    */
   public String getRecurranceType()
   {
      return recurranceType;
   }

   /**
    * Returns whether this event is recurring or not.
    * @return True if event recurs, false otherwise.
    */
   public boolean isRecurring()
   {
      return recurring;
   }

   /**
    * Check if one event is the same as another.
    */
   public boolean equals(Object obj)
   {
      if (this == obj)
         return true; // reflexive
      if (obj == null)
         return false; // test for null
      if (this.getClass() != obj.getClass())
         return false; // symmetric

      Event target = (Event) obj;
      if (!eventName.equals(target.eventName))
         return false;
      if (!type.equals(target.type))
         return false;
      if (!description.equals(target.description))
         return false;
      if (recurring != target.recurring)
         return false;
//      if (!recurranceType.equals(target.recurranceType))
//         return false;

      // checks every element of this bag is contained in the parameter bag
      for (int i = 0; i < daysOfWeek.length; i++)
         if (daysOfWeek[i] != target.daysOfWeek[i])
            return false;

      return true;
   }

   /**
    * Return the string representation of the start time.
    * 
    * @return start time in hh:mm(am/pm) format
    */
   public String getStartTimeString()
   {
      String ampm = (startTime.get(Calendar.AM_PM) < 1) ? "AM" : "PM";

      int hour = startTime.get(Calendar.HOUR);
      if (hour == 0)
          hour = 12;
      
      return String.format("%d:%02d%s", hour, startTime
            .get(Calendar.MINUTE), ampm);
   }

   /**
    * Return the string of the end time
    * 
    * @return end time in hh:mm(am/pm) format
    */
   public String getEndTimeString()
   {
      String ampm = (endTime.get(Calendar.AM_PM) < 1) ? "AM" : "PM";

      int hour = endTime.get(Calendar.HOUR);
      if (hour == 0)
          hour = 12;
      
      return String.format("%d:%02d%s", hour, endTime
            .get(Calendar.MINUTE), ampm);
   }

}
